home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / D-G / GemsI / Original / DigitalDissolve.c < prev    next >
Encoding:
Text File  |  1992-06-16  |  4.4 KB  |  123 lines  |  [TEXT/MPS ]

  1. /* A Digital Dissolve Effect
  2. by Mike Morton
  3. from "Graphics Gems", Academic Press, 1990
  4. */
  5.  
  6. int reg;                /* current sequence element */
  7. reg = 1;                    /* start in any non-zero state */
  8. if (reg & 1)                /* is the bottom bit set? */
  9.     reg = (reg >>1) ^ MASK;    /* yes: toss out 1 bit; */
  10.                                 /* XOR in mask */
  11. else reg = reg >>1;        /* no: toss out 0 bit */
  12.  
  13.  
  14.  
  15. dissolve1 (height, width)    /* first version of the dissolve                                 /* algorithm */
  16.     int height, width;    /* number of rows, columns */
  17. {
  18.     int pixels, lastnum;    /* number of pixels; */
  19.                             /* last pixel's number */
  20.     int regwidth;        /* "width" of sequence generator */
  21.     register long mask;    /* mask to XOR with to*/
  22.                         /* create sequence */
  23.     register unsigned long element; 
  24.                         /* one element of random sequence */
  25.     register int row, column;
  26.                         /* row and column numbers for a pixel */
  27.  
  28.       /* Find smallest register which produces enough pixel numbers */
  29.      pixels = height * width; /* compute number of pixels */
  30.                             /* to dissolve */
  31.      lastnum = pixels-1;    /* find last element (they go 0..lastnum) */
  32.      regwidth = bitwidth (lastnum); /* how wide must the */
  33.                                   /* register be? */
  34.      mask = randmasks [regwidth];    /* which mask is for that width? */
  35.  
  36.      /* Now cycle through all sequence elements. */
  37.  
  38.       element = 1;    /* 1st element (could be any nonzero) */
  39.  
  40.  
  41.       do {
  42.         row = element / width;    /* how many rows down is this pixel? */
  43.         column = element % width;    /* and how many columns across? */
  44.         if (row < height)    /* is this seq element in the array? */
  45.           copy (row, column);    /* yes: copy the (r,c)'th pixel */
  46.  
  47.         /* Compute the next sequence element */
  48.         if (element & 1)        /* is the low bit set? */
  49.           element = (element >>1)^mask; /* yes: shift value, */
  50.                                      /* XOR in mask */
  51.         else element = (element >>1); /* no: just shift the value */
  52.      } while (element != 1);        /* loop until we return  */
  53.                                     /* to original element */
  54.      copy (0, 0);        /* kludge: the loop doesn't produce (0,0) */
  55. }                        /* end of dissolve1() */
  56.  
  57.  
  58.  
  59.  
  60. int bitwidth (N)    /* find "bit-width" needed to represent N */
  61.     unsigned int N;    /* number to compute the width of */
  62. {
  63.      int width = 0;    /* initially, no bits needed to represent N */
  64.      while (N != 0) {    /* loop 'til N has been whittled down to 0 */
  65.         N >>= 1;        /* shift N right 1 bit (NB: N is unsigned) */
  66.         width++;        /* and remember how wide N is */
  67.       }            /* end of loop shrinking N down to nothing *
  68.       return (width);    /* return bit positions counted */
  69.  
  70. }                        /* end of bitwidth() */
  71.  
  72.  
  73.  
  74. dissolve2 (height, width)    /* fast version of the dissolve algorithm */
  75.     int height, width;    /* number of rows, columns */
  76. {
  77.     int rwidth, cwidth;    /* bit width for rows, for columns */
  78.     int regwidth;        /* "width" of sequence generator */
  79.     register long mask;    /* mask to XOR with to create sequence */
  80.     register int rowshift;    /* shift distance to get row  */
  81.                             /* from element */
  82.     register int colmask; /* mask to extract column from element */
  83.     register unsigned long element; /* one element of random */                                     /* sequence */
  84.     register int row, column;    /* row and column for one pixel */
  85.  
  86.  
  87.       /* Find the mask to produce all rows and columns. */
  88.  
  89.     rwidth = bitwidth (height); /* how many bits needed for height? */
  90.     cwidth = bitwidth (width);  /* how many bits needed for width? */
  91.     regwidth = rwidth + cwidth; /* how wide must the register be? */
  92.     mask = randmasks [regwidth]; /* which mask is for that width? */
  93.  
  94.  /* Find values to extract row and col numbers from each element. */
  95.     rowshift = cwidth; /* find dist to shift to get top bits (row) */
  96.     colmask = (1<<cwidth)-1;    /* find mask to extract  */
  97.                             /* bottom bits (col) */
  98.  
  99.       /* Now cycle through all sequence elements. */
  100.  
  101.     element = 1;    /* 1st element (could be any nonzero) */
  102.     do {
  103.         row = element >> rowshift; /* find row number for this pixel */
  104.         column = element & colmask; /* and how many columns across? */
  105.         if ((row < height)    /* does element fall in the array? */
  106.             && (column < width))   /* ...must check row AND column */
  107.         copy (row, column);    /* in bounds: copy the (r,c)'th pixel */
  108.  
  109.         /* Compute the next sequence element */
  110.         if (element & 1)        /* is the low bit set? */
  111.         element = (element >>1)^mask; /* yes: shift value, /*
  112.                                    /* XOR in mask */
  113.         else element = (element >>1); /* no: just shift the value */
  114.     } while (element != 1);     /* loop until we return to */
  115.                             /*  original element */
  116.  
  117.     copy (0, 0);        /* kludge: element never comes up zero */
  118. }                    /* end of dissolve2() */
  119.  
  120.  
  121.  
  122.  
  123.